import requests
import re
import sys
import getopt
import time

requests.packages.urllib3.disable_warnings()

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/80.0.3970.5 Safari/537.36',
    'Referer': 'https://www.bilibili.com/'
}
p_size_pat = '"videos":(.*?)'  # 获取最大页数正则
pages_pat = '"pages":\\[.*?\\]'
page_part_pat = '"page":(.*?),.{0,40}"part":"(.*?)"'
url = 'https://www.bilibili.com/video/#bvid?p=#page&vd_source=a248f44e3c87683800d8c8bac20ed6b4'


def get_music_list(video_url, session=requests.session()):
    """
    返回页码与标题的关系
    """
    res = session.get(url=video_url, headers=headers, verify=False)
    doc = res.text
    page_content = re.compile(pages_pat, re.S).findall(doc)[0]
    page_part_s = re.compile(page_part_pat, re.S).findall(page_content)
    result = []
    for page_part in page_part_s:
        result.append(page_part)
    return result


def down_music(video_id: str, page_v: str, title: str, pan_dir: str, session=requests.session()):
    video_url = f'https://www.bilibili.com/video/{video_id}?p={page_v}&vd_source=a248f44e3c87683800d8c8bac20ed6b4'
    res = session.get(url=video_url, headers=headers, verify=False)
    doc = res.text
    a_pat = '"audio":.*?"baseUrl":\\s{0,3}"(.*?)"'
    audio_url = re.compile(a_pat, re.S).findall(doc)[0]
    print(f'正在下载 {title} 的音频····')
    headers.update({'Referer': video_url})
    # zjl_util.download(audio_url, os.getcwd() + '/' + title + '.mp3', header=headers)
    upload_to_189(audio_url, title + '.mp3', pan_dir, u_headers=headers)


def upload_to_189(down_url, file_name, remote_folder='/我的音乐/', u_headers=None):
    """下载文件并显示过程
        :param down_url: 资源地址
        :param file_name: 保存的文件名
        :param remote_folder: 网盘目录
        :param u_headers: 请求头
        """
    if u_headers is None:
        u_headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
            "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
            "Accept-Encoding": "gzip, deflate, br",
            "Connection": "keep-alive",
            "Upgrade-Insecure-Requests": "1"
        }
    t1 = time.time()
    down_data_count = 0
    speed_count = 0
    chunk_size = 1024
    m = 1024 * 1024
    k = 1024
    interval = 1
    data_es = []
    with requests.get(down_url, stream=True, headers=u_headers, timeout=20) as r:
        for chunk in r.iter_content(chunk_size):
            if len(chunk) == 0:
                continue
            data_length = len(chunk)
            down_data_count += data_length
            speed_count += data_length
            data_es.append(chunk)

            t2 = time.time()
            if t2 - t1 > interval:
                size_str = str(down_data_count)
                if down_data_count > m:
                    size_str = str(down_data_count / m) + "M"
                elif down_data_count > k:
                    size_str = str(down_data_count / k) + "K"

                speed_str = str(speed_count)
                if speed_count > m:
                    speed_str = str(speed_count / m) + "M"
                elif speed_count > k:
                    speed_str = str(speed_count / k) + "K"
                # print("                                     \t\t")
                print(size_str + "\t" + speed_str + "/s")
                t1 = t2
                speed_count = 0
    # 上传文件
    data = {'remote_dir': remote_folder}
    upload_url = 'http://127.0.0.1:8189/189/upload'
    files = {'file': (file_name, b''.join(data_es))}
    r = None
    for k in range(10):
        try:
            r = requests.post(upload_url, data=data, files=files)
            j = r.json()
            if 'id' not in j or j['id'] is None or j['id'] == '':
                continue
            else:
                break
        except Exception as e:
            print('cause Exception while upload mpe:', e, r.text)
    print('uploaded ', remote_folder, file_name)


if __name__ == '__main__':
    v_id = ''
    pan_folder = ''
    opts, args = getopt.getopt(sys.argv[1:], "hi:r:")
    for o, a in opts:
        if o == '-h':
            print("python3 down_bilibili_music.py -i 视频号 -r 网盘目录路径")
            exit()
        if o == '-i':
            v_id = a
        if o == '-r':
            pan_folder = a
    if v_id == '':
        v_id = input('请输入视频号：')
    if pan_folder == '':
        pan_folder = input('请输入网盘目录：')
    if v_id.strip() == '':
        sys.exit()
    url = 'https://www.bilibili.com/video/' + v_id + '/?spm_id_from=333.788&vd_source=a248f44e3c87683800d8c8bac20ed6b4'
    page_title_s = get_music_list(url)
    down_list = []
    i = 1
    for i in range(0, len(page_title_s)):
        print(i + 1, page_title_s[i])
    range_start = input('从第几集开始？')
    range_end = input('到第几集结束？')
    if int(range_start) <= int(range_end):
        for i in range(int(range_start), int(range_end)+1):
            page_title = page_title_s[i - 1]
            down_music(v_id, page_title[0], page_title[1].replace('《', '').replace('》', ''), pan_folder)
